home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / plnk081.zip / pilot-link.0.8.1 / pilot-xfer.c.orig < prev    next >
Text File  |  1997-08-05  |  13KB  |  614 lines

  1. /* pilot-xfer.c:  Pilot Database transfer utility
  2.  *
  3.  * (c) 1996, Kenneth Albanowski.
  4.  *
  5.  * This is free software, licensed under the GNU Public License V2.
  6.  * See the file COPYING for details.
  7.  */
  8.  
  9. #include <stdio.h>
  10. #ifdef __EMX__
  11. #include <getopt.h>
  12. #include <sys/types.h>
  13. #endif
  14. #include <sys/stat.h>
  15. #include <signal.h>
  16. #include "pi-source.h"
  17. #include "pi-socket.h"
  18. #include "pi-file.h"
  19. #include "pi-dlp.h"
  20.  
  21. #define pi_mktag(c1,c2,c3,c4) (((c1)<<24)|((c2)<<16)|((c3)<<8)|(c4))
  22.  
  23. int sd = 0;
  24. char * device = "/dev/pilot";
  25. char * progname;
  26.  
  27. char * exclude[100];
  28. int numexclude = 0;
  29.  
  30. RETSIGTYPE SigHandler(int signal);
  31.  
  32. void MakeExcludeList(char *efile) {
  33.     char temp[1024];
  34.     FILE *f = fopen(efile,"r");
  35.  
  36.     while((fgets(temp,sizeof(temp),f)) != NULL) {
  37.         if (temp[strlen(temp)-1] == '\n')
  38.             temp[strlen(temp)-1] = '\0';
  39.         printf("Will exclude: %s\n",temp);
  40.         exclude[numexclude++] = strdup(temp);
  41.     }
  42. }
  43.  
  44. void Connect(void) {
  45.   struct pi_sockaddr addr;
  46.   int ret;
  47.  
  48.   if (sd!=0)
  49.     return;
  50.     
  51.   signal(SIGHUP, SigHandler);
  52.   signal(SIGINT, SigHandler);
  53.   signal(SIGSEGV, SigHandler);
  54.       
  55.   if (!(sd = pi_socket(PI_AF_SLP, PI_SOCK_STREAM, PI_PF_PADP))) {
  56.     perror("pi_socket");
  57.     exit(1);
  58.   }
  59.  
  60.   addr.pi_family = PI_AF_SLP;
  61.   strcpy(addr.pi_device,device);
  62.   
  63.   ret = pi_bind(sd, (struct sockaddr*)&addr, sizeof(addr));
  64.   if(ret == -1) {
  65.     fprintf(stderr, "Unable to bind to port '%s'.\n(Please see '%s -h' for information setting the port).\n", device, progname);
  66.     exit(1);
  67.   }
  68.     
  69.   printf("Waiting for connection on %s (press the HotSync button now)...\n", device);
  70.  
  71.   ret = pi_listen(sd,1);
  72.   if(ret == -1) {
  73.     perror("pi_listen");
  74.     exit(1);
  75.   }
  76.  
  77.   sd = pi_accept(sd,0,0);
  78.   if(sd == -1) {
  79.     perror("pi_accept");
  80.     exit(1);
  81.   }
  82.  
  83.   puts("Connected");
  84. }
  85.  
  86. void Disconnect(void)
  87. {
  88.   if(sd==0)
  89.     return;
  90.     
  91.   dlp_EndOfSync(sd, 0);
  92.   pi_close(sd);
  93.   sd = 0;
  94. }
  95.  
  96. RETSIGTYPE SigHandler(int signal)
  97. {
  98.   puts("Abort on signal!");
  99.   Disconnect();
  100.   exit(3);
  101. }
  102.  
  103. void VoidSyncFlags(void)
  104. {
  105.   struct PilotUser U;
  106.   Connect();
  107.   if (dlp_ReadUserInfo(sd, &U)>=0) {
  108.     U.lastSyncPC = 0x00000000; /* Hopefully unique constant, to tell
  109.                                   any Desktop software that databases
  110.                                   have been altered, and that a slow
  111.                                   sync is necessary */
  112.     U.lastSyncDate = U.successfulSyncDate = time(0);
  113.     dlp_WriteUserInfo(sd, &U);
  114.   } 
  115. }
  116.  
  117. void Backup(char * dirname)
  118. {
  119.   int i;
  120.   
  121.   Connect();
  122.   
  123.   mkdir(dirname,0700);
  124.  
  125.   i = 0;
  126.   for(;;) {
  127.       struct DBInfo info;
  128.       struct pi_file * f;
  129.         int x;
  130.         int skip = 0;
  131.       char name[256];
  132.  
  133.         if (dlp_OpenConduit(sd)<0) {
  134.       puts("Exiting on cancel, all data _not_ backed up.");
  135.           exit(1);
  136.         }
  137.         
  138.       if( dlp_ReadDBList(sd, 0, 0x80, i, &info) < 0)
  139.           break;
  140.       i = info.index + 1;
  141.  
  142.         for(x = 0; x < numexclude; x++) {
  143.             /* printf("Skipcheck:%s:%s:\n",exclude[x],info.name); */
  144.             if(strcmp(exclude[x],info.name) == 0) {
  145.                 printf("Excluding '%s'...\n",info.name);
  146.                 skip = 1;
  147.             }
  148.         }
  149.  
  150.         if(skip == 1)
  151.             continue;
  152.  
  153.       sprintf(name, "%s/%s", dirname, info.name);
  154.       if (info.flags & dlpDBFlagResource)
  155.         strcat(name,".prc");
  156.       else
  157.         strcat(name,".pdb");
  158.         
  159.       printf("Backing up '%s'... ", name);
  160.       fflush(stdout);
  161.       
  162.       /* Ensure that DB-open flag is not kept */
  163.       info.flags &= 0xff;
  164.       
  165.       f = pi_file_create(name, &info);
  166.       if (f==0) {
  167.         printf("Failed, unable to create file\n");
  168.         break;
  169.       }
  170.       
  171.       if(pi_file_retrieve(f, sd, 0)<0)
  172.         printf("Failed, unable to back up database\n");
  173.       else
  174.         printf("OK\n");
  175.       pi_file_close(f);
  176.   }
  177.   printf("Backup done.\n");
  178. }
  179.  
  180. void Fetch(char * dbname)
  181. {
  182.   struct DBInfo info;
  183.   char name[256];
  184.         struct pi_file * f;
  185.         
  186.   Connect();
  187.  
  188.   if (dlp_OpenConduit(sd)<0) {
  189.     puts("Exiting on cancel, all data _not_ backed up.");
  190.     exit(1);
  191.   }
  192.       
  193.   if (dlp_FindDBInfo(sd, 0, 0, dbname, 0, 0, &info)<0) {
  194.     printf("Unable to locate database '%s', fetch skipped.\n", dbname);
  195.     return;
  196.   }
  197.         
  198.   strcpy(name, dbname);
  199.   if (info.flags & dlpDBFlagResource)
  200.     strcat(name,".prc");
  201.   else
  202.     strcat(name,".pdb");
  203.         
  204.   printf("Fetching '%s'... ", name);
  205.   fflush(stdout);
  206.  
  207.   info.flags &= 0xff;
  208.       
  209.   f = pi_file_create(name, &info);
  210.   if (f==0) {
  211.     printf("Failed, unable to create file\n");
  212.     return;
  213.   }
  214.       
  215.   if(pi_file_retrieve(f, sd, 0)<0)
  216.     printf("Failed, unable to back up database\n");
  217.   else
  218.     printf("OK\n");
  219.   pi_file_close(f);
  220.  
  221.   printf("Fetch done.\n");
  222. }
  223.  
  224. void Delete(char * dbname)
  225. {
  226.   struct DBInfo info;
  227.   Connect();
  228.  
  229.   if (dlp_OpenConduit(sd)<0) {
  230.     puts("Exiting on cancel, all data _not_ backed up.");
  231.     exit(1);
  232.   }
  233.  
  234.   dlp_FindDBInfo(sd, 0, 0, dbname, 0, 0, &info);
  235.   
  236.   printf("Deleting '%s'... ", dbname);
  237.   if (dlp_DeleteDB(sd, 0, dbname)>=0) {
  238.         if (info.type == pi_mktag('b','o','o','t')) {
  239.            printf(" (rebooting afterwards) ");
  240.         }
  241.       printf("OK\n");
  242.   } else {
  243.       printf("Failed, unable to delete database\n");
  244.   }
  245.   fflush(stdout);
  246.       
  247.   printf("Delete done.\n");
  248. }
  249.  
  250. struct db {
  251.       char name[256];
  252.       int flags;
  253.       unsigned long creator;
  254.       unsigned long type;
  255.       int maxblock;
  256. };
  257.  
  258. int compare(struct db * d1, struct db * d2)
  259. {
  260.   /* types of 'appl' sort later then other types */
  261.   if(d1->creator == d2->creator)
  262.     if(d1->type != d2->type) {
  263.       if(d1->type == pi_mktag('a','p','p','l'))
  264.         return 1;
  265.       if(d2->type == pi_mktag('a','p','p','l'))
  266.         return -1;
  267.     }
  268.   return d1->maxblock < d2->maxblock;
  269. }
  270.  
  271. void Restore(char * dirname)
  272. {
  273.   DIR * dir;
  274.   struct dirent * dirent;
  275.   struct DBInfo info;
  276.   struct db * db[256];
  277.   int dbcount = 0;
  278.   int i,j,max,size;
  279.   struct pi_file * f;
  280.  
  281.   dir = opendir(dirname);
  282.   
  283.   while( (dirent = readdir(dir)) ) {
  284.         char name[256];
  285.         
  286.         if (dirent->d_name[0] == '.')
  287.            continue;
  288.  
  289.     
  290.     db[dbcount] = (struct db*)malloc(sizeof(struct db));
  291.     
  292.     sprintf(db[dbcount]->name, "%s/%s", dirname, dirent->d_name);
  293.     
  294.     f = pi_file_open(db[dbcount]->name);
  295.       if (f==0) {
  296.         printf("Unable to open '%s'!\n", name);
  297.         break;
  298.       }
  299.       
  300.       pi_file_get_info(f, &info);
  301.       
  302.       db[dbcount]->creator = info.creator;
  303.       db[dbcount]->type = info.type;
  304.       db[dbcount]->flags = info.flags;
  305.       db[dbcount]->maxblock = 0;
  306.       
  307.       pi_file_get_entries(f, &max);
  308.       
  309.       for (i=0;i<max;i++) {
  310.         if (info.flags & dlpDBFlagResource)
  311.           pi_file_read_resource(f, i, 0, &size, 0, 0);
  312.         else
  313.           pi_file_read_record(f, i, 0, &size, 0, 0,0 );
  314.           
  315.         if (size > db[dbcount]->maxblock)
  316.           db[dbcount]->maxblock = size;
  317.       }
  318.       
  319.       pi_file_close(f);
  320.       dbcount++;
  321.   }
  322.  
  323.   closedir(dir);
  324.  
  325. #ifdef DEBUG      
  326.   printf("Unsorted:\n");
  327.   for (i=0;i<dbcount;i++) {
  328.      printf("%d: %s\n", i, db[i]->name);
  329.      printf("  maxblock: %d\n", db[i]->maxblock);
  330.      printf("  creator: '%s'\n", printlong(db[i]->creator));
  331.      printf("  type: '%s'\n", printlong(db[i]->type));
  332.   }
  333. #endif
  334.   
  335.   for (i=0;i<dbcount;i++)
  336.     for (j=i+1;j<dbcount;j++) 
  337.       if (compare(db[i],db[j])>0) {
  338.         struct db * temp = db[i];
  339.         db[i] = db[j];
  340.         db[j] = temp;
  341.       }
  342.  
  343. #ifdef DEBUG      
  344.   printf("Sorted:\n");
  345.   for (i=0;i<dbcount;i++) {
  346.      printf("%d: %s\n", i, db[i]->name);
  347.      printf("  maxblock: %d\n", db[i]->maxblock);
  348.      printf("  creator: '%s'\n", printlong(db[i]->creator));
  349.      printf("  type: '%s'\n", printlong(db[i]->type));
  350.   }
  351. #endif
  352.  
  353.   Connect();
  354.   
  355.   for (i=0;i<dbcount;i++) {
  356.  
  357.     if ( dlp_OpenConduit(sd) < 0) {
  358.        puts("Exiting on cancel. All data not restored.");
  359.        exit(1);
  360.     }
  361.  
  362.       f = pi_file_open(db[i]->name);
  363.       if (f==0) {
  364.         printf("Unable to open '%s'!\n", db[i]->name);
  365.         break;
  366.       }
  367.       printf("Restoring %s... ", db[i]->name);
  368.       fflush(stdout);
  369.       if(pi_file_install(f, sd, 0)<0)
  370.         printf("failed.\n");
  371.       else
  372.         printf("OK\n");
  373.       pi_file_close(f);
  374.   }
  375.   
  376.   VoidSyncFlags();
  377.  
  378.   printf("Restore done\n");
  379. }
  380.  
  381. void Install(char * filename)
  382. {
  383.   struct pi_file * f;
  384.   
  385.   Connect();
  386.  
  387.   if ( dlp_OpenConduit(sd) < 0) {
  388.     puts("Exiting on cancel. All data not restored.");
  389.     exit(1);
  390.   }
  391.  
  392.   f = pi_file_open(filename);
  393.   if (f==0) {
  394.     printf("Unable to open '%s'!\n", filename);
  395.     return;
  396.   }
  397.   printf("Installing %s... ", filename);
  398.   fflush(stdout);
  399.   if(pi_file_install(f, sd, 0)<0)
  400.     printf("failed.\n");
  401.   else
  402.     printf("OK\n");
  403.   pi_file_close(f);
  404.   
  405.   VoidSyncFlags();
  406.  
  407.   printf("Install done\n");
  408. }
  409.  
  410. void Merge(char * filename)
  411. {
  412.   struct pi_file * f;
  413.   
  414.   Connect();
  415.  
  416.   if ( dlp_OpenConduit(sd) < 0) {
  417.     puts("Exiting on cancel. All data not restored.");
  418.     exit(1);
  419.   }
  420.  
  421.   f = pi_file_open(filename);
  422.   if (f==0) {
  423.     printf("Unable to open '%s'!\n", filename);
  424.     return;
  425.   }
  426.   
  427.   
  428.   printf("Merging %s... ", filename);
  429.   fflush(stdout);
  430.   if(pi_file_merge(f, sd, 0)<0)
  431.     printf("failed.\n");
  432.   else
  433.     printf("OK\n");
  434.   pi_file_close(f);
  435.   
  436.   VoidSyncFlags();
  437.  
  438.   printf("Merge done\n");
  439. }
  440.  
  441. void List(void)
  442. {
  443.   struct DBInfo info;
  444.   int i;
  445.   
  446.   Connect();
  447.  
  448.   if ( dlp_OpenConduit(sd) < 0) {
  449.     puts("Exiting on cancel. All data not restored.");
  450.     exit(1);
  451.   }
  452.   
  453.   printf("Reading list of databases...\n");
  454.   
  455.   i = 0;
  456.   for(;;) {
  457.       if( dlp_ReadDBList(sd, 0, 0x80, i, &info) < 0)
  458.           break;
  459.       i = info.index + 1;
  460.       
  461.       printf("'%s'\n", info.name);
  462.   }
  463.   
  464.   printf("List done.\n");
  465. }
  466.  
  467. void Purge(void)
  468. {
  469.   struct DBInfo info;
  470.   int i;
  471.   int h;
  472.   
  473.   Connect();
  474.  
  475.   if ( dlp_OpenConduit(sd) < 0) {
  476.     puts("Exiting on cancel. All data not restored.");
  477.     exit(1);
  478.   }
  479.   
  480.   printf("Reading list of databases to purge...\n");
  481.   
  482.   i = 0;
  483.   for(;;) {
  484.       if( dlp_ReadDBList(sd, 0, 0x80, i, &info) < 0)
  485.           break;
  486.       i = info.index + 1;
  487.       
  488.       if (info.flags & 1)
  489.           continue; /* skip resource databases */
  490.       
  491.       printf("Purging deleted records from '%s'... ", info.name);
  492.       
  493.       h = 0;
  494.       if ((dlp_OpenDB(sd, 0, 0x40|0x80, info.name, &h)>=0) &&
  495.         (dlp_CleanUpDatabase(sd, h)>=0) &&
  496.           (dlp_ResetSyncFlags(sd,h)>=0) ) {
  497.           printf("OK\n");
  498.       } else {
  499.           printf("Failed\n");
  500.       }
  501.       
  502.       if (h!=0)
  503.           dlp_CloseDB(sd, h);
  504.       
  505.   }
  506.   
  507.   VoidSyncFlags();
  508.   
  509.   printf("Purge done.\n");
  510. }
  511.  
  512. void Help(void)
  513. {
  514.       printf("Usage: %s [%s] command(s)\n\n",progname,TTYPrompt);
  515.       printf("Where a command is one or more of: -b(ackup)  backupdir\n");
  516.       printf("                                   -r(estore) backupdir\n");
  517.       printf("                                   -i(nstall) filename(s)\n");
  518.       printf("                                   -m(erge)   filename(s)\n");
  519.       printf("                                   -f(etch)   dbname(s)\n");
  520.       printf("                                   -d(elete)  dbname(s)\n");
  521.       printf("                                   -e(xclude) filename(s)\n");
  522.       printf("                                   -p(urge)\n");
  523.       printf("                                   -l(ist)\n");
  524.       printf("\n");
  525.       printf("The serial port to connect to may be specified by the PILOTPORT\n");
  526.       printf("environment variable instead of the command line. If not specified\n");
  527.       printf("anywhere, it will default to /dev/pilot.\n");
  528.       exit(0);
  529. }
  530.  
  531. int main(int argc, char *argv[])
  532. {
  533.   int c;
  534.   int lastmode = 0;
  535.   char *tmp;
  536. #ifdef sun
  537.   extern char* optarg;
  538.   extern int optind;
  539. #endif
  540.  
  541.  
  542.   progname = argv[0];
  543.  
  544.   if (argc < 2) {
  545.     Help();
  546.   }
  547.  
  548.   tmp = getenv("PILOTPORT");
  549.   if (tmp != NULL)
  550.     device = tmp;
  551.   
  552. #ifdef __EMX__
  553.   optmode = GETOPT_KEEP;
  554. #else
  555.   optind=1;
  556. #endif  
  557.   while (argv[optind] != NULL) {
  558.     c = getopt(argc, argv, "b:e:r:i:m:f:d:plh");
  559.     if (c == EOF) {
  560.     optarg=argv[optind++];
  561.     c = lastmode;
  562.     if (lastmode=='b' || lastmode=='r' || lastmode=='l' || lastmode=='p') {
  563.         fprintf(stderr, "'%c', only accepts one argument!\n", lastmode);
  564.         continue;
  565.     }
  566.     if (c == 0) {
  567.       device = optarg;
  568.       continue;
  569.     }
  570.     }
  571.     switch (c) {
  572.     case 'b':
  573.       Backup(optarg);
  574.       break;
  575.     case 'r':
  576.       Restore(optarg);
  577.       break;
  578.     case 'i':
  579.       Install(optarg);
  580.       break;
  581.     case 'm':
  582.       Merge(optarg);
  583.       break;
  584.     case 'f':
  585.       Fetch(optarg);
  586.       break;
  587.     case 'd':
  588.       Delete(optarg);
  589.       break;
  590.     case 'e':
  591.       MakeExcludeList(optarg);
  592.       break;
  593.     case 'p':
  594.       Purge();
  595.       break;
  596.     case 'l':
  597.       List();
  598.       break;
  599.     default:
  600.       break;
  601.     case 'h': case '?':
  602.       Help();
  603.     }
  604.     lastmode=c;
  605.   }
  606.   if (lastmode==0)
  607.     Help();
  608.   
  609.   Disconnect();
  610.   
  611.   exit(0);
  612. }
  613.  
  614.